package util;

import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

public class RegexUtil {

    public static Regexer is(String regex) {

        return new Regexer(Pattern.compile(regex));
    }

    public static Regexer is(Pattern regex) {

        return new Regexer(regex);
    }

    public static class Regexer {

        private Pattern pattern;

        private Regexer(Pattern pattern) { this.pattern = pattern; }

        // 扫描目标文本，返回一个包含匹配内容的流
        public Stream<String> scan(String context) {

            Iterator<String> scanIterator = new Iterator<String>() {

                private Matcher matcher = pattern.matcher(context);

                @Override public boolean hasNext() {

                    return matcher.find();
                }

                @Override public String next() {

                    return matcher.group();
                }
            };

            return StreamSupport.stream(((Iterable<String>)() -> scanIterator).spliterator(), false);
        }

        // 扫描目标文本，返回一个包含匹配内容和其捕获分组流，其中List[0]是匹配内容,List[1..-1]是匹配分组
        public Stream<List<String>> scanList(String context) {

            Iterator<List<String>> scanIterator = new Iterator<List<String>>() {

                private Matcher matcher = pattern.matcher(context);

                @Override public boolean hasNext() {

                    return matcher.find();
                }

                @Override public List<String> next() {

                    return IntStream.range(0, matcher.groupCount() + 1).mapToObj(matcher::group).collect(Collectors.toList());
                }
            };

            return StreamSupport.stream(((Iterable<List<String>>)() -> scanIterator).spliterator(), false);
        }

        // 扫描目标文本，返回其捕获分组的流
        public Stream<List<String>> scanGroup(String context) {

            return scanList(context).map((list) -> { list.remove(0); return list; });
        }

        // 使用正则匹配分割字符串 返回分割开来的字符串流
        public Stream<String> split(String context) {

            return pattern.splitAsStream(context);
        }
    }
}
